package com.yfp.client.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.api.WxMaSubscribeService;
import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.yfp.client.config.WxMaConfiguration;
import com.yfp.client.config.WxPayProperties;
import com.yfp.client.domain.Client;
import com.yfp.client.domain.OrderCombo;
import com.yfp.client.domain.OrderDetail;
import com.yfp.client.domain.OrderList;
import com.yfp.client.service.*;
import com.yfp.common.core.enums.OrderTypeEnum;
import com.yfp.common.core.utils.StringUtils;
import com.yfp.client.service.*;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class WxInfoServiceImpl implements WxInfoService {

    @Resource
    private WxPayProperties wxPayProperties;
    @Resource
    private ClientService clientService;
    @Resource
    private OrderComboService orderComboService;
    @Resource
    private OrderDetailService orderDetailService;
    @Resource
    private OrderListService orderListService;

    @Override
    public void notifyCookingStatus(String orderId, String orderDetailId) {
        log.info("notifyCookingStatus,orderId:{},orderDetailId:{}", orderId, orderDetailId);
        OrderCombo orderCombo = orderComboService.getById(orderId);
        List<OrderList> orderLists = orderListService.listByOrderSn(orderId);
        // 判断是否为设备点餐
        boolean anyMatch = orderLists.stream().anyMatch(item -> StrUtil.equals(OrderTypeEnum.Device.getCode().toString(), item.getOrderType()));
        if (anyMatch) {
            return;
        }
        Client client = clientService.getById(orderCombo.getUserId());

        // 组装消息
        HashMap<String, String> sendMsgData = this.assembleCookingStatusMessage(orderDetailId);
        this.sendSubscribeMsg(client.getOpenId(), "cvXN4cVzVAtR_H6kZz7CN-7CM_dp1cf7OtOW1S9ywcc", sendMsgData);
    }

    @Override
    public void notifyTakeFood(String orderId, String orderDetailId, Date date) {
        log.info("notifyTakeFood,orderId:{},orderDetailId:{},date:{}", orderId, orderDetailId, date);
        OrderCombo orderCombo = orderComboService.getById(orderId);
        List<OrderList> orderLists = orderListService.listByOrderSn(orderId);
        // 判断是否为设备点餐
        boolean anyMatch = orderLists.stream().anyMatch(item -> StrUtil.equals(OrderTypeEnum.Device.getCode().toString(), item.getOrderType()));
        if (anyMatch) {
            return;
        }
        Client client = clientService.getById(orderCombo.getUserId());

        // 组装消息
        HashMap<String, String> sendMsgData = this.assembleTakeFoodMessage(orderId, orderDetailId, date);
        this.sendSubscribeMsg(client.getOpenId(), "gN9DKGzX7t6TdIdfN6OCqeBnW1_rq-M2SkPtOiuBP_M", sendMsgData);
    }

    @Override
    public void sendSubscribeMsg(String toUser, String templateId, HashMap<String, String> sendMsgData) {
        log.info("sendSubscribeMsg,toUser:{},templateId:{},sendMsgData:{}", toUser, templateId, sendMsgData);
        WxMaService wxService = WxMaConfiguration.getMaService(wxPayProperties.getConfigs().get(0).getAppId());
        WxMaSubscribeService subscribeService = wxService.getSubscribeService();

        List<WxMaSubscribeMessage.MsgData> msgDataList = sendMsgData.entrySet().stream().map(entry -> new WxMaSubscribeMessage.MsgData(entry.getKey(), entry.getValue())).collect(Collectors.toList());
        WxMaSubscribeMessage build = WxMaSubscribeMessage.builder().toUser(toUser).templateId(templateId).data(msgDataList).build();
        try {
            subscribeService.sendSubscribeMsg(build);
        } catch (WxErrorException e) {
            log.error("sendSubscribeMsg:{}", e.getMessage());
        }
    }

    @Override
    public HashMap<String, String> assembleCookingStatusMessage(String orderListId) {

        OrderList orderList = orderListService.getById(orderListId);

        // 炒制状态通知
        HashMap<String, String> sendMsgData = MapUtil.newHashMap();
        // 设备ID
        sendMsgData.put("character_string2", StringUtils.limitString(orderList.getMachineId(), 32));
        // 炒制菜品
        sendMsgData.put("thing4", StringUtils.limitString(orderList.getComboName(), 20));
        // 炒制状态
        sendMsgData.put("phrase5", "开始制作");
        // 设备地点
        sendMsgData.put("thing1", StringUtils.limitString(orderList.getPositionName(), 20));
        // 温馨提示
        sendMsgData.put("thing6", "菜品已开始炒制，稍后即可享受现炒美味");
        return sendMsgData;
    }

    @Override
    public HashMap<String, String> assembleTakeFoodMessage(String orderId, String orderListId, Date date) {
        List<OrderDetail> orderDetails = orderDetailService.listByOrderId(orderId);
        String pickupNumList = orderDetails.stream().map(item -> item.getPickupNum()).sorted().collect(Collectors.joining(","));

        List<OrderList> orderLists = orderListService.listByOrderSn(orderId);
        OrderList orderList = orderListService.getById(orderListId);

        Map<String, List<OrderList>> orderListMapByComboId = orderLists.stream().collect(Collectors.groupingBy(OrderList::getComboId));
        String comboInfo = orderListMapByComboId.entrySet().stream().map(item -> {
            String key = item.getKey();
            List<OrderList> value = item.getValue();
            OrderList first = CollUtil.getFirst(value);
            String comboName = first.getComboName();
            int size = value.size();
            return String.format("%s*%d", comboName, size);
        }).collect(Collectors.joining(","));

        // 取餐提醒
        HashMap<String, String> sendMsgData = MapUtil.newHashMap();
        // 取餐号码
        sendMsgData.put("character_string4", StringUtils.limitString(pickupNumList, 32));
        // 餐品详情
        sendMsgData.put("thing5", StringUtils.limitString(comboInfo, 20));
        // 取餐时间
        sendMsgData.put("time6", DateUtil.formatDateTime(date));
        // 取餐地址
        sendMsgData.put("thing7", StringUtils.limitString(orderList.getPositionName(), 20));
        // 温馨提示
        sendMsgData.put("thing11", "您的餐品已放入餐柜，请速来取餐");
        return sendMsgData;
    }


}
